/**
 * Copyright (C) 2010 Cloudfarming <info@cloudfarming.nl>
 *
 * Licensed under the Eclipse Public License - v 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package nl.cloudfarming.client.planning.tactical;

import nl.cloudfarming.client.db.test.BaseContextTest;
import nl.cloudfarming.client.db.test.BaseContextTest.MockContextGlobalProvider;
import nl.cloudfarming.client.db.test.BaseContextTest.MockDialogDisplayer;
import java.util.concurrent.CountDownLatch;
import nl.cloudfarming.client.messaging.MessageEventKey;
import nl.cloudfarming.client.messaging.Message;
import nl.cloudfarming.eventbus.GuiEvent;
import nl.cloudfarming.eventbus.GuiEventKey;
import nl.cloudfarming.eventbus.GuiEventListener;
import org.openide.nodes.Node;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import nl.cloudfarming.client.model.ProductionUnit;
import java.beans.IntrospectionException;

import nl.cloudfarming.client.model.FieldPlan;
import nl.cloudfarming.client.model.Field;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.TimeUnit;
import javax.swing.JButton;
import static junit.framework.Assert.*;
import nl.cloudfarming.eventbus.GuiEventBus;
import static org.mockito.Mockito.*;

/**
 *
 * @author Merijn Zengers
 */
public class LinkProductionUnitToFieldIT extends BaseContextTest {

    //Tests if a Message is generated when a LinkProductionUnitToFieldAction is executed
    //@Test
    public void balloonAfterLinkTest() throws IntrospectionException, InterruptedException {
        TacticalPlanningService service = mock(TacticalPlanningService.class);
        
        Field field = mock(Field.class);
        //Field is needed in LinkProductionUnitAction so add it to the mockGlobalContext
        MockContextGlobalProvider.add(field);
        when(service.getLookup()).thenReturn(MockContextGlobalProvider.getLookup());
        FieldPlan fieldPlan = mock(FieldPlan.class);

        ProductionUnit productionUnit = mock(ProductionUnit.class);
        List<ProductionUnit> productionUnits = new ArrayList<ProductionUnit>();
        productionUnits.add(productionUnit);

        when(fieldPlan.getProductionUnits()).thenReturn(productionUnits);

        FieldPlanNode node = new FieldPlanNode(fieldPlan, service);
        //DropDown is based on the available nodes in the Explorer manager
        when(service.getFieldplanNodes()).thenReturn(new Node[]{node});

        // make a countDownLatch so the action can finish before asserting
        CountDownLatch latch = new CountDownLatch(1);

        MockMessageInbox inbox = new MockMessageInbox(latch);
        //Add the mock inbox as listener to the guiEventBus
        GuiEventBus.addListener(inbox);

        LinkProductionUnitToFieldAction action = new LinkProductionUnitToFieldAction();

        action.setService(service);

        action.actionPerformed(null);

        assertNotNull(MockDialogDisplayer.options);
        assertTrue(MockDialogDisplayer.options[0] instanceof JButton);

        JButton okButton = (JButton) MockDialogDisplayer.options[0];

        ActionEvent event = mock(ActionEvent.class);
        //Execute Ok button
        for (ActionListener al : okButton.getActionListeners()) {
            al.actionPerformed(event);
        }

        //Test
        assertTrue("Timeout while waiting for gui event to be triggered", latch.await(10, TimeUnit.MILLISECONDS));
    }

    public class MockMessageInbox implements GuiEventListener<Message> {

        private final CountDownLatch latch;

        public MockMessageInbox(CountDownLatch latch) {
            this.latch = latch;
        }

        @Override
        public void onEvent(GuiEvent<Message> event) {
            latch.countDown();
        }

        @Override
        public boolean listensTo(GuiEventKey guiEventKey) {
            return MessageEventKey.NEW_MESSAGE.equals(guiEventKey);
        }

        @Override
        public String getModuleName() {
            return TEST_MODULE;
        }
    }
}
